home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 9 / CDACTUAL9.iso / share / Dos / VARIOS / pascal / SWAG9605.DDD / 0011_Vesa Driver Interface.pas < prev    next >
Encoding:
Pascal/Delphi Source File  |  1996-05-31  |  14.6 KB  |  526 lines

  1. UNIT VESAdrv;
  2. INTERFACE
  3. const ProgName   :string[80] = 'VESA driver interface by Pε'#$0D#$0A'$';
  4.       ProgVersion:word = $0102;  { programmed for VESA version 1.2 }
  5.       MaxVertical =      480*2;       { max. vertical lines you need }
  6.                                       { double if 2 pages required }
  7.  
  8.       VesaSign   :longint = $41534556; { = 'VESA' }
  9.       StatusOk   :WORD    = $004f;     { default ok response after int 10 }
  10.                                               {.........!.........!.........!}
  11.       VesaErrors :ARRAY[0..5] OF STRING[30] =('Vesa init ok.                 ',
  12.                                               '?Error getting vesainfo.      ',
  13.                                               '?Vesa not detected.           ',
  14.                                               '?Vesa not detected.           ',
  15.                                               '?Error getting vesamodeinfo.  ',
  16.                                               '?Error opening vesamode.      ');
  17.       MaxBanks = 256;    { maximum bank switch }
  18.  
  19. type
  20.  TVerticalPosInfo = ARRAY[0..MaxVertical-1] OF RECORD { extra help for finding}
  21.                              Address :Word;             { memory addres }
  22.                              Bank:Byte;             { memory bank }
  23.                              reserved:byte;
  24.                              end;
  25.  
  26.  TVesaInfoBlock = record
  27.         VESASignature      : longint; {'VESA' check as number}
  28.         VESAVersion        : word;    { version hi.lo }
  29.         OEMStringPtr       : pointer; { pointer to OEM string }
  30.         Capabilities       : longint; { Capabilities field }
  31.         VideoModePtr       : pointer; { pointer to supported modes }
  32.         TotalMemory        : word;    { x64k available memory }
  33.         reserved           : array[1..236] of byte; {unused yet}
  34.         end;
  35.  
  36.  TVesaModeInfoBlock = record
  37.         ModeAttributes     : word;    { mode attributes                    }
  38.         WinAAttributes     : byte;    { window A attributes                }
  39.         WinBAttributes     : byte;    { window B attributes                }
  40.         WinGranularity     : word;    { window granularity                 }
  41.         WinSize            : word;    { window size                        }
  42.         WinASegment        : word;    { window A start segment             }
  43.         WinBSegment        : word;    { window B start segment             }
  44.         WinFuncPtr         : pointer; { pointer to windor function         }
  45.         BytesPerScanLine   : word;    { bytes per scan line                }
  46.         XResolution        : word;    { horizontal resolution              }
  47.         YResolution        : word;    { vertical resolution                }
  48.         XCharSize          : byte;    { character cell width               }
  49.         YCharSize          : byte;    { character cell height              }
  50.         NumberOfPlanes     : byte;    { number of memory planes            }
  51.         BitsPerPixel       : byte;    { bits per pixel                     }
  52.         NumberOfBanks      : byte;    { number of banks                    }
  53.         MemoryModel        : byte;    { memory model type                  }
  54.         BankSize           : byte;    { bank size in kb                    }
  55.         NumberOfImagePages : byte;    { number of images                   }
  56.         Reserved           : byte;    { reserved for page function         }
  57.         RedMaskSize        : byte;    { size of direct color red mask      }
  58.         RedFieldPosition   : byte;    { bit position of LSB of red mask    }
  59.         GreenMaskSize      : byte;    { size of direct color green mask    }
  60.         GreenFieldPosition : byte;    { bit position of LSB of green mask  }
  61.         BlueMaskSize       : byte;    { size of direct color blue mask     }
  62.         BlueFieldPosition  : byte;    { bit position of LSB of blue mask   }
  63.         RsvdMaskSize       : byte;    { size of direct color reserved mask }
  64.         DirectColorModeInfo: byte;    { Direct Color mode attributes       }
  65.         Reserved2          : array[1..216] of byte; { remainder            }
  66.        end;
  67.  
  68.   function InitVesaMode(RequestMode:word;ClearScreen:BOOLEAN):word;
  69.   procedure PutPixel(X,Y:Integer; C:Word);
  70.   procedure DrawBitMap(X,Y, XS,YS:Integer;ImageData:Pointer);
  71.   procedure Draw0BitMap(X,Y, XS,YS:Integer;ImageData:Pointer);
  72.   procedure SetDisplayStart(X,Y:Word);
  73.   procedure CloseVesaMode;
  74.  
  75. var
  76.  VesaInfo       : TVesaInfoBlock;     { get your own info here }
  77.  VesaModeInfo   : TVesaModeInfoBlock; { get your own info here }
  78.  VerticalPosInfo: TVerticalPosInfo;   { get your own info here }
  79.  BankTable      : ARRAY[0..MaxBanks] OF Word;
  80.  
  81.  CurrentBank,
  82.  WritePage,
  83.  VisualPage       : word;
  84.  WinSizeBytes     : word;  { winsize in bytes..   0 = 64k }
  85.  
  86. IMPLEMENTATION
  87. {==== initialize video mode ====}
  88. function InitVesaMode(RequestMode:word;ClearScreen:BOOLEAN):word; assembler;
  89. asm
  90.    xor  si,si        { Error step value }
  91.    inc  si           { start with one }
  92.  
  93.    mov  ax,ds
  94.    mov  es,ax
  95.    mov  ax,$4f00;    { return SuperVGA information }
  96.    mov  di, OFFSET VesaInfo; { into buffer VesaInfo }
  97.    int  $10;
  98.  
  99.    cmp  ax,StatusOk; { Status okay ? }
  100. {1}   jnz @ErrorInit;    { no, then halt init }
  101.  
  102.    inc  si            { next check }
  103.    mov  ax, WORD PTR VesaInfo.VESASignature;  { check first two chars }
  104.    cmp  ax, WORD PTR VesaSign
  105. {2}   jnz @ErrorInit
  106.  
  107.    inc  si            { next check }
  108.    mov  ax, WORD PTR VesaInfo.VESASignature+2;  { check next two chars }
  109.    cmp  ax, WORD PTR VesaSign+2
  110. {3}   jnz @ErrorInit
  111.  
  112.    { primary test for VESA done, try to get videomode info }
  113.    inc  si            { next check }
  114.    mov  ax, $4f01               { return videomode information }
  115.    mov  cx, RequestMode         { requested mode }
  116.    mov  di, OFFSET VesaModeInfo { into buffer VesaModeInfo }
  117.    int  $10;
  118.  
  119.    cmp  ax, StatusOk;           { did this work out good? }
  120. {4}   jnz @ErrorInit
  121.  
  122.    { start opening videomode }
  123.    inc  si            { next check }
  124.    mov  ax, $4f02;
  125.    mov  bh, ClearScreen;        { must clear screen }
  126.    xor  bh, $01;                { invert bit }
  127.    shl  bh, 7;                  { move bit to d15 }
  128.    xor  bl, bl;                 { clear lower byte }
  129.    or   bx, RequestMode;        { combine with videomode }
  130.    int  $10;
  131.  
  132.    cmp  ax, StatusOk            { did this work out good? }
  133. {5}   jnz @ErrorInit
  134.  
  135.    { build vertical pos info block }
  136.    inc  si               { next check }
  137.    mov  cx, MaxVertical  { how many times }
  138.    mov  di, OFFSET VerticalPosInfo;
  139.  
  140.    xor  bx, bx;                 { startbank=0 }
  141.    xor  ax, ax;                 { address  =0 }
  142.    mov  dx, WORD PTR VesaModeInfo.WinSize;
  143.    mov  WinSizeBytes, dx
  144.    xchg dl, dh                  { multiply this with 1024 }
  145.    shl  dh, 2
  146. (*    mov  dx, $1000 *)
  147.  
  148.    { set info }
  149. @VPosLoop:
  150.    mov  ds:[di+0],ax            { place addres in vpos infoblock}
  151.    mov  ds:[di+2],bl            { place bank in vpos infoblock }
  152.    mov  ds:[di+3],bh            { place bank in vpos infoblock }
  153.  
  154.    add  di,4                    { add to next pos. in array}
  155.    add  ax, WORD PTR VesaModeInfo.XResolution { increment address}
  156.    jc   @IncBank                { in case 64k buffer carry is gen. here! }
  157.  
  158.    cmp  ax, dx                  { check if bank is passed}
  159.    jb  @DoLoop;
  160.  
  161.    sub  ax, dx                  { decrement ax with size to start again 4k-buf}
  162. @IncBank:
  163.    inc  bx;
  164.  
  165. @DoLoop:
  166.    Loop @VPosLoop;
  167.  
  168.    { built bankswitchtable }
  169.  
  170.    mov  di, OFFSET BankTable
  171.    xor  bx, bx        { start at bank 0 }
  172.  
  173. @BankLoop:
  174.    mov   ax,bx        { get banknr }
  175.  
  176.    mov   cx, 64
  177.    mul   cx
  178.     mov   cx, WORD PTR VesaModeInfo.WinGranularity
  179.    jcxz    @@be
  180.    div   cx
  181. @@be:
  182.    mov   ds:[di],ax   { save value }
  183.    inc   di
  184.    inc   di
  185.  
  186.    inc   bx
  187.    cmp   bx,MaxBanks
  188.    jb    @BankLoop
  189.  
  190.    { buffer has been built for easy use! }
  191.    XOR  CX,CX
  192.    mov  CurrentBank, CX   { clear current bank to 0 first time}
  193.    mov  WritePage,   CX   { write to page 0 }
  194.    mov  VisualPage,  CX   { visual page = 0 }
  195.    xor  bx,bx;            { perpare for int.}
  196.    mov  dx,cx;            { get banknr from cx }
  197.    mov  ax,$4f05;         { irq init }
  198.    int $10;
  199.  
  200. (*    jmp  @okinit; *)
  201.  
  202. { all ok part }
  203. @OkInit:
  204.    XOR  AX,AX
  205. @ErrorInit:
  206. @End:
  207. end;
  208.  
  209. {====}
  210. procedure PutPixel(X,Y:Integer; C:Word); assembler;
  211. asm
  212.          mov     ax,Y
  213.          add     ax,WritePage
  214.  
  215.          mov     di,X
  216.          mov     dx,VesaModeInfo.BytesPerScanLine
  217.          mul     dx
  218.          add     di,ax
  219.          adc     dx,0
  220.          cmp     dx,CurrentBank         { out of current window boundary? }
  221.          je      @@1                    { no }
  222. {==== bankswitch ====}
  223.        MOV     BX,DX
  224.          MOV     CurrentBank,BX
  225.  
  226.        ADD     BX, BX
  227.        ADD     BX, OFFSET BankTable
  228.        mov     DX, DS:[BX]
  229.        mov     AX, $4F05
  230.        xor     BX, BX
  231.        int     10h
  232. @@1:
  233.        mov     AX ,c
  234.        mov     es,SegA000
  235.        mov     es:[di], al
  236. end;
  237.  
  238. (*asm
  239.     mov  ax,y
  240.     add  ax,WritePage
  241.     shl  ax,2
  242.     mov  si, OFFSET VerticalPosInfo
  243.    add  si, ax
  244.  
  245.    mov  ax, ds:[si] { get address }
  246.    mov  es,SegA000  { get video segment }
  247.    mov  di,ax       { get video address }
  248.  
  249.    mov  ax, ds:[si+2] { get bank }
  250.    add  di,x          { add x coordinate to address }
  251.    adc  ax,0          { perhaps bank add }
  252.  
  253.    cmp  ax, CurrentBank;  { check if bank is same }
  254.    jz @PutPix;            { bank is already ok! }
  255.  
  256.    mov  CurrentBank,ax;   { set new bank }
  257.    xor  bx,bx;            { perpare for int.}
  258.     mov  dx,ax;            { get banknr from ax }
  259.    mov  ax,$4f05;         { irq init }
  260.    int $10;
  261.  
  262. @PutPix:
  263.    mov  ax,C;             { get color}
  264.    mov  es:[di],ax;       { finally put the pixel}
  265.    end;
  266. *)
  267.  
  268. procedure SetBank; near;assembler;
  269. { IN: BX = Which bank }
  270. asm
  271.    ADD  BX, BX
  272.    ADD  BX, OFFSET BankTable
  273.    mov  DX, DS:[BX]
  274.    mov  AX, $4F05
  275.    xor  BX, BX
  276.    int  10h
  277. end;
  278.  
  279. procedure DrawBitMap(X,Y, XS,YS:Integer;ImageData:Pointer); assembler;
  280. var
  281.     SaveDS, MemInc,CurBank : word;
  282.     Count,BPLine, WinGran : word;
  283. asm
  284.          cld
  285.          mov     SaveDS,ds
  286.          mov     ax,CurrentBank
  287.          mov     CurBank,ax
  288.        mov     ax,VesaModeInfo.WinGranularity
  289.        mov     WinGran,ax
  290.          mov     ax,Y
  291.          add     ax,WritePage
  292.  
  293.          mov     di,X
  294.          mov     dx,VesaModeInfo.BytesPerScanLine
  295.          mul     dx
  296.          add     di,ax
  297.          adc     dx,0
  298.          cmp     dx,CurBank            { out of current window boundary? }
  299.          je      @@1                    { no }
  300. {==== bankswitch ====}
  301.        MOV     BX,DX
  302.          MOV     CurBank,BX
  303.  
  304.        ADD     BX, BX
  305.        ADD     BX, OFFSET BankTable
  306.        mov     DX, DS:[BX]
  307.        mov     AX, $4F05
  308.        xor     BX, BX
  309.        int     10h
  310.  
  311. @@1:   mov     bx,VesaModeInfo.BytesPerScanLine
  312. { move from buffer to video memory }
  313.          mov     es,SegA000
  314.          lds     si, ImageData
  315.          mov     cx, XS
  316.          mov     BPLine,cx
  317.          sub     bx,cx
  318.          mov     MemInc,bx
  319.          mov     ax, YS
  320.          mov     Count,ax
  321.  
  322.        { check if switch is necessary, for one line! }
  323. @@2:   mov     ax,di
  324.        add     ax,CX  { BPLine }
  325.        jnc     @one_row  { no carry so one full row }
  326.  
  327.        { check what's before }
  328.        xor     cx,cx
  329.        sub     cx,di
  330.  
  331.        shr     cx,1         { copy partially line directly }
  332.        rep     movsw
  333.        jnc     @pfini       { ready with one partial line }
  334.        movsb                { just one byte with copy , no rep is slow start }
  335.  
  336. @pfini:
  337.        push    ax           { save rest for later }
  338.        inc     CurBank
  339.  
  340. {==== bankswitch ====}
  341.        mov     ax,CurBank
  342.        mov     cx, 64
  343.        mul     cx
  344.         mov     cx, WinGran
  345. (*        or      cx,cx *)
  346.        jcxz      @@e2
  347.        div     cx
  348.         mov     dx, ax
  349.        mov     ax, $4F05
  350.        xor     bx, bx
  351.        int     10h
  352. @@e2:
  353.  
  354.        pop     ax
  355. @@2_1: { switch done, do other half }
  356.        mov     cx,ax
  357.  
  358. @One_Row:
  359.        shr     cx,1         { copy partially line directly, part 2 after switch }
  360.        rep     movsw
  361.        jnc     @fini       { ready with one partial line }
  362.        movsb                { just one byte with copy , no rep is slow start }
  363.  
  364. @fini:  { Finished, add for next line }
  365.        add     di,MemInc
  366.        jc      @@2_2sw
  367.        mov     cx,BPLine
  368.        dec     Count
  369.        jnz     @@2
  370.        jmp     @@EndDrw
  371. @@2_2sw:
  372.        inc     CurBank
  373.  
  374. {==== bankswitch ====}
  375.        mov     ax, CurBank
  376.        mov     cx, 64
  377.        mul     cx
  378.         mov     cx, WinGran
  379. (*        or      cx,cx *)
  380.        jcxz      @@e3
  381.        div     cx
  382.         mov     dx, ax
  383.        mov     ax, $4F05
  384.        xor     bx, bx
  385.        int     10h
  386. @@e3:
  387.  
  388.        mov     cx,BPLine
  389.        dec     Count
  390.        jnz     @@2
  391.  
  392. @@EndDrw:
  393.        mov     ds,SaveDS
  394.        mov     ax,CurBank
  395.        mov     CurrentBank,ax
  396. end;
  397.  
  398. procedure Draw0BitMap(X,Y, XS,YS:Integer;ImageData:Pointer); assembler;
  399. var
  400.     SaveDS : word;
  401.     MemInc : word;
  402.     OldBank,CurBank : word;
  403.     Count,BPLine : word;
  404. asm
  405.          cld
  406.          mov     SaveDS,ds
  407.          mov     ax,CurrentBank
  408.          mov     CurBank,ax
  409.          mov     ax,Y
  410.          add     ax,WritePage
  411.  
  412.          mov     di,X
  413.          mov     dx,VesaModeInfo.BytesPerScanLine
  414.          mul     dx
  415.          add     di,ax
  416.          adc     dx,0
  417.          cmp     dx,CurBank            { out of current window boundary? }
  418.          je      @@1                    { no }
  419.          mov     CurBank,dx
  420.        mov     bx,dx
  421.          call    SetBank               { move memory window to new position }
  422.  
  423. @@1:   mov     bx,VesaModeInfo.BytesPerScanLine
  424. { move from buffer to video memory }
  425.          mov     es,SegA000
  426.          lds     si, ImageData
  427.          mov     cx, XS
  428.          mov     BPLine,cx
  429.          sub     bx,cx
  430.          mov     MemInc,bx
  431.          mov     ax, YS
  432.          mov     Count,ax
  433.  
  434.        { check if switch is necessary, for one line! }
  435. @@2:   mov     ax,di
  436.        add     ax,CX   {BPLine}
  437.        jnc     @One_row  { no carry so one full row }
  438.  
  439. @no_one_row:   { there is a switch now in this line }
  440.        { check what's before }
  441.        push    ax           { save rest for later }
  442.        xor     cx,cx
  443.        sub     cx,di
  444.        jcxz    @pfini
  445.  
  446.        xor     ah,ah
  447. @part1opnieuw:
  448.        lodsb
  449.        cmp     al,ah
  450.        jz      @part1zero    { a zero value, so don't put this}
  451.        mov     es:[di],al
  452. @part1zero:
  453.        inc     di
  454.        dec     cx
  455.        jnz     @part1opnieuw
  456.  
  457. @pfini:
  458.        inc     CurBank
  459.        push    ds
  460.        mov     bx,CurBank
  461.        mov     ds,SaveDs
  462.        call    SetBank
  463.        pop     ds
  464.  
  465. @@2_1: { switch done, do other half }
  466.        pop     cx
  467.        jcxz    @fini
  468. @One_row:
  469.        xor     ah,ah
  470. @part2opnieuw:
  471.        lodsb
  472.        cmp     al,ah
  473.        jz      @part2zero    { a zero value, so don't put this}
  474.        mov     es:[di],al
  475. @part2zero:
  476.        inc     di
  477.        dec     cx
  478.        jnz     @part2opnieuw
  479.  
  480. @fini:  { Finished, add for next line }
  481.        add     di,MemInc
  482.        jc      @@2_2sw
  483.        mov     cx,BPLine
  484.        dec     Count
  485.        jnz     @@2
  486.        jmp     @@EndDrw
  487. @@2_2sw:
  488.        inc     CurBank
  489.  
  490.        push    ds
  491.        mov     bx,CurBank
  492.        mov     ds,SaveDs
  493.        call    SetBank
  494.  
  495.        pop     ds
  496.        mov     cx,BPLine
  497.        dec     Count
  498.        jnz     @@2
  499.  
  500. @@EndDrw:
  501.        mov     ds,SaveDS
  502. end;
  503.  
  504. {====}
  505. procedure SetDisplayStart(X,Y:Word); assembler;
  506. asm
  507.    mov  ax,$4f07;
  508.    xor  bx,bx
  509.    mov  cx,x
  510.    mov  dx,y
  511.    int  $10;
  512. end;
  513. {===}
  514. procedure CloseVesaMode; assembler;
  515. asm
  516.    mov  ax,$4f03;   { standard way of reseting videocard }
  517.    int  $10;
  518.    mov  ax,$0003;   { standard way of reseting videocard }
  519.    int  $10;
  520. end;
  521.  
  522.  
  523. begin
  524.  
  525. end.
  526.